# - Find MS Visual C++
#
#  VC_DIR          - where to find Visual C++
#  VC_INCLUDE_DIR  - where to find headers
#  VC_INCLUDE_DIRS - where to find headers
#  VC_LIBRARY_DIR  - where to find libraries
#  VC_FOUND        - True if MSVC found

IF(CMAKE_CXX_COMPILER)
  SET(_COMPILER ${CMAKE_CXX_COMPILER})
  SET(_VERSION ${CMAKE_CXX_COMPILER_VERSION})
ELSEIF(CMAKE_C_COMPILER)
  SET(_COMPILER ${CMAKE_C_COMPILER})
  SET(_VERSION ${CMAKE_C_COMPILER_VERSION})
ELSE()
  MESSAGE(FATAL_ERROR "No way to determine Visual C++ location")
ENDIF()

IF(MSVC_VERSION LESS 1910)    
  IF(MSVC_VERSION LESS 1500)
    MESSAGE(FATAL_ERROR "Unsupported version of Visual C++ (minimum version is 2008)")
  ELSEIF(MSVC_VERSION LESS 1600)
    SET(MSVC_TOOLSET "90")
    SET(_NAME "2008")
  ELSEIF(MSVC_VERSION LESS 1700)
    SET(MSVC_TOOLSET "100")
    SET(_NAME "2010")
  ELSEIF(MSVC_VERSION LESS 1800)
    SET(MSVC_TOOLSET "110")
    SET(_NAME "2012")
  ELSEIF(MSVC_VERSION LESS 1900)
    SET(MSVC_TOOLSET "120")
    SET(_NAME "2013")
  ELSE()
    SET(MSVC_TOOLSET "140")
    SET(_NAME "2015")
  ENDIF()

  STRING(REGEX REPLACE "/bin/.+" "" VC_DIR ${_COMPILER})

  MESSAGE(STATUS "Found Visual C++ ${_NAME} (${_VERSION}) in ${VC_DIR}")
ELSE()
  # Toolset = version of runtime DLLs
  SET(MSVC_TOOLSET "140")

  IF(MSVC_VERSION LESS 1920)
    SET(_NAME "2017")
  ELSE()
    SET(_NAME "2019")
  ENDIF()

  STRING(REGEX REPLACE "/MSVC/.+" "/MSVC" VC_DIR ${_COMPILER})

  FILE(GLOB MSVC_TOOLCHAIN_VERSIONS RELATIVE ${VC_DIR} "${VC_DIR}/*")

  IF(MSVC_TOOLCHAIN_VERSIONS)
    LIST(SORT MSVC_TOOLCHAIN_VERSIONS)
    LIST(REVERSE MSVC_TOOLCHAIN_VERSIONS)
  ENDIF()

  IF(MSVC_TOOLCHAIN_VERSIONS)
    LIST(GET MSVC_TOOLCHAIN_VERSIONS 0 MSVC_TOOLCHAIN_VERSION)

    SET(VC_DIR "${VC_DIR}/${MSVC_TOOLCHAIN_VERSION}")

    MESSAGE(STATUS "Found Visual C++ ${_NAME} (${_VERSION} with toolchain ${MSVC_TOOLCHAIN_VERSION}) in ${VC_DIR}")
  ELSE()
    MESSAGE(FATAL_ERROR "Unable to find Visual C++ in ${VC_DIR}")
  ENDIF()
ENDIF()

IF(NOT VC_INCLUDE_DIR AND VC_DIR AND EXISTS "${VC_DIR}")
  SET(VC_INCLUDE_DIR "${VC_DIR}/include")
  IF(EXISTS "${VC_INCLUDE_DIR}")
    SET(VC_FOUND ON)
  ENDIF()
ENDIF()

SET(MSVC_REDIST_DIR "${EXTERNAL_PATH}/redist")

IF(NOT EXISTS "${MSVC_REDIST_DIR}")
  SET(MSVC_REDIST_DIR "${VC_DIR}/redist")

  IF(NOT EXISTS "${MSVC_REDIST_DIR}")
    SET(MSVC_REDIST_DIR)
  ENDIF()
ENDIF()

IF(MSVC_REDIST_DIR)
  IF(MSVC_VERSION GREATER 1909)
    # If you have VC++ 2017 Express, put x64/Microsoft.VC141.CRT/*.dll in ${EXTERNAL_PATH}/redist
    # original files whould be in ${VC_DIR}/Redist/MSVC/14.11.25325/x64/Microsoft.VC141.CRT
    SET(MSVC14_REDIST_DIR "${MSVC_REDIST_DIR}")
  ELSEIF(MSVC14)
    SET(MSVC14_REDIST_DIR "${MSVC_REDIST_DIR}")
  ELSEIF(MSVC12)
    # If you have VC++ 2013 Express, put x64/Microsoft.VC120.CRT/*.dll in ${EXTERNAL_PATH}/redist
    SET(MSVC12_REDIST_DIR "${MSVC_REDIST_DIR}")
  ELSEIF(MSVC11)
    # If you have VC++ 2012 Express, put x64/Microsoft.VC110.CRT/*.dll in ${EXTERNAL_PATH}/redist
    SET(MSVC11_REDIST_DIR "${MSVC_REDIST_DIR}")
  ELSEIF(MSVC10)
    # If you have VC++ 2010 Express, put x64/Microsoft.VC100.CRT/*.dll in ${EXTERNAL_PATH}/redist
    SET(MSVC10_REDIST_DIR "${MSVC_REDIST_DIR}")
  ELSEIF(MSVC90)
    SET(MSVC90_REDIST_DIR "${MSVC_REDIST_DIR}")
  ELSEIF(MSVC80)
    SET(MSVC80_REDIST_DIR "${MSVC_REDIST_DIR}")
  ENDIF()
ENDIF()

IF(VC_INCLUDE_DIR)
  MESSAGE(STATUS "Using VC++ headers from ${VC_INCLUDE_DIR}")
ELSE()
  MESSAGE(FATAL_ERROR "Unable to find VC++ headers")
ENDIF()

SET(VC_INCLUDE_DIRS ${VC_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${VC_INCLUDE_DIR})
